/*
 * HSStepper
 * @version: 3.2.3
 * @author: Preline Labs Ltd.
 * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)
 * Copyright 2024 Preline Labs Ltd.
 */

import { dispatch } from '../../utils'

import { IStepper, IStepperItem, IStepperOptions } from './interfaces'

import HSBasePlugin from '../base-plugin'
import { ICollectionItem } from '../../interfaces'

class HSStepper extends HSBasePlugin<{}> implements IStepper {
  private currentIndex: number | null
  private readonly mode: string | null
  private isCompleted: boolean | null

  private totalSteps: number | null

  private navItems: IStepperItem[] | null
  private contentItems: IStepperItem[] | null
  private backBtn: HTMLElement | null
  private nextBtn: HTMLElement | null
  private skipBtn: HTMLElement | null
  private completeStepBtn: HTMLElement | null
  private completeStepBtnDefaultText: string | null
  private finishBtn: HTMLElement | null
  private resetBtn: HTMLElement | null

  private onNavItemClickListener:
    | {
        el: HTMLElement
        fn: () => void
      }[]
    | null
  private onBackClickListener: () => void
  private onNextClickListener: () => void
  private onSkipClickListener: () => void
  private onCompleteStepBtnClickListener: () => void
  private onFinishBtnClickListener: () => void
  private onResetBtnClickListener: () => void

  constructor(el: HTMLElement, options?: IStepperOptions) {
    super(el, options)

    const data = el.getAttribute('data-stepper')
    const dataOptions: IStepperOptions = data ? JSON.parse(data) : {}
    const concatOptions = {
      ...dataOptions,
      ...options
    }

    this.currentIndex = concatOptions?.currentIndex || 1
    this.mode = concatOptions?.mode || 'linear'
    this.isCompleted = typeof concatOptions?.isCompleted !== 'undefined' ? concatOptions?.isCompleted : false

    this.totalSteps = 1

    this.navItems = []
    this.contentItems = []

    this.onNavItemClickListener = []

    this.init()
  }

  private navItemClick(item: IStepperItem) {
    this.handleNavItemClick(item)
  }

  private backClick() {
    this.handleBackButtonClick()

    if (this.mode === 'linear') {
      const currentNavItem = this.navItems.find(({ index }) => index === this.currentIndex)
      const currentContentItem = this.contentItems.find(({ index }) => index === this.currentIndex)

      if (!currentNavItem || !currentContentItem) return

      if (currentNavItem.isCompleted) {
        currentNavItem.isCompleted = false
        currentNavItem.isSkip = false

        currentNavItem.el.classList.remove('is-valid', 'skipped')
      }

      if (currentContentItem.isCompleted) {
        currentContentItem.isCompleted = false
        currentContentItem.isSkip = false

        currentContentItem.el.classList.remove('is-valid', 'skipped')
      }

      if (this.mode === 'linear' && this.currentIndex !== this.totalSteps) {
        if (this.nextBtn) this.nextBtn.style.display = ''
        if (this.completeStepBtn) this.completeStepBtn.style.display = ''
      }

      this.showSkipButton()
      this.showFinishButton()
      this.showCompleteStepButton()
    }
  }

  private nextClick() {
    this.fireEvent('beforeNext', this.currentIndex)
    dispatch('beforeNext.stepper', this.el, this.currentIndex)

    if (this.getNavItem(this.currentIndex)?.isProcessed) {
      this.disableAll()

      return false
    }

    this.goToNext()
  }

  private skipClick() {
    this.handleSkipButtonClick()

    if (this.mode === 'linear' && this.currentIndex === this.totalSteps) {
      if (this.nextBtn) this.nextBtn.style.display = 'none'
      if (this.completeStepBtn) this.completeStepBtn.style.display = 'none'
      if (this.finishBtn) this.finishBtn.style.display = ''
    }
  }

  private completeStepBtnClick() {
    this.handleCompleteStepButtonClick()
  }

  private finishBtnClick() {
    this.fireEvent('beforeFinish', this.currentIndex)
    dispatch('beforeFinish.stepper', this.el, this.currentIndex)

    if (this.getNavItem(this.currentIndex)?.isProcessed) {
      this.disableAll()

      return false
    }

    this.handleFinishButtonClick()
  }

  private resetBtnClick() {
    this.handleResetButtonClick()
  }

  private init() {
    this.createCollection(window.$hsStepperCollection, this)

    this.buildNav()
    this.buildContent()
    this.buildButtons()
    this.setTotalSteps()
  }

  private getUncompletedSteps(inIncludedSkipped: boolean = false) {
    return this.navItems.filter(({ isCompleted, isSkip }) =>
      inIncludedSkipped ? !isCompleted || isSkip : !isCompleted && !isSkip
    )
  }

  private setTotalSteps() {
    this.navItems.forEach(item => {
      const { index } = item

      if (index > this.totalSteps) this.totalSteps = index
    })
  }

  // Nav
  private buildNav() {
    this.el.querySelectorAll('[data-stepper-nav-item]').forEach(el => this.addNavItem(el as HTMLElement))

    this.navItems.forEach(item => this.buildNavItem(item))
  }

  private buildNavItem(item: IStepperItem) {
    const { index, isDisabled, el } = item

    if (index === this.currentIndex) this.setCurrentNavItem()

    if (this.mode !== 'linear' || isDisabled) {
      this.onNavItemClickListener.push({
        el,
        fn: () => this.navItemClick(item)
      })

      el.addEventListener('click', this.onNavItemClickListener.find(navItem => navItem.el === el).fn)
    }
  }

  private addNavItem(el: HTMLElement) {
    const {
      index,
      isFinal = false,
      isCompleted = false,
      isSkip = false,
      isOptional = false,
      isDisabled = false,
      isProcessed = false,
      isInvalid = false
    } = JSON.parse(el.getAttribute('data-stepper-nav-item'))

    if (isCompleted) el.classList.add('is-valid')
    if (isSkip) el.classList.add('skipped')
    if (isDisabled) {
      if (el.tagName === 'BUTTON' || el.tagName === 'INPUT') {
        el.setAttribute('disabled', 'disabled')
      }

      el.classList.add('disabled')
    }
    if (isInvalid) el.classList.add('is-invalid')

    this.navItems.push({
      index,
      isFinal,
      isCompleted,
      isSkip,
      isOptional,
      isDisabled,
      isProcessed,
      isInvalid,
      el: el as HTMLElement
    })
  }

  private setCurrentNavItem() {
    this.navItems.forEach(item => {
      const { index, el } = item

      if (index === this.currentIndex) this.setCurrentNavItemActions(el)
      else this.unsetCurrentNavItemActions(el)
    })
  }

  private setCurrentNavItemActions(el: HTMLElement) {
    el.classList.add('active')

    this.fireEvent('active', this.currentIndex)
    dispatch('active.stepper', this.el, this.currentIndex)
  }

  private getNavItem(n = this.currentIndex) {
    return this.navItems.find(({ index }) => index === n)
  }

  private setProcessedNavItemActions(item: IStepperItem) {
    item.isProcessed = true

    item.el.classList.add('processed')
  }

  private setErrorNavItemActions(item: IStepperItem) {
    item.isInvalid = true

    item.el.classList.add('is-invalid')
  }

  private unsetCurrentNavItemActions(el: HTMLElement) {
    el.classList.remove('active')
  }

  private handleNavItemClick(item: IStepperItem) {
    const { index } = item

    this.currentIndex = index

    this.setCurrentNavItem()
    this.setCurrentContentItem()

    this.checkForTheFirstStep()
  }

  // Content
  private buildContent() {
    this.el.querySelectorAll('[data-stepper-content-item]').forEach(el => this.addContentItem(el as HTMLElement))

    this.navItems.forEach(item => this.buildContentItem(item))
  }

  private buildContentItem(item: IStepperItem) {
    const { index } = item

    if (index === this.currentIndex) this.setCurrentContentItem()
  }

  private addContentItem(el: HTMLElement) {
    const {
      index,
      isFinal = false,
      isCompleted = false,
      isSkip = false
    } = JSON.parse(el.getAttribute('data-stepper-content-item'))

    if (isCompleted) el.classList.add('is-valid')
    if (isSkip) el.classList.add('skipped')

    this.contentItems.push({
      index,
      isFinal,
      isCompleted,
      isSkip,
      el: el as HTMLElement
    })
  }

  private setCurrentContentItem() {
    if (this.isCompleted) {
      const finalContentItem = this.contentItems.find(({ isFinal }) => isFinal)
      const otherContentItems = this.contentItems.filter(({ isFinal }) => !isFinal)
      finalContentItem.el.style.display = ''
      otherContentItems.forEach(({ el }) => (el.style.display = 'none'))

      return false
    }

    this.contentItems.forEach(item => {
      const { index, el } = item

      if (index === this.currentIndex) this.setCurrentContentItemActions(el)
      else this.unsetCurrentContentItemActions(el)
    })
  }

  private hideAllContentItems() {
    this.contentItems.forEach(({ el }) => (el.style.display = 'none'))
  }

  private setCurrentContentItemActions(el: HTMLElement) {
    el.style.display = ''
  }

  private unsetCurrentContentItemActions(el: HTMLElement) {
    el.style.display = 'none'
  }

  private disableAll() {
    const currentNavItem = this.getNavItem(this.currentIndex)
    currentNavItem.isInvalid = false
    currentNavItem.isCompleted = false
    currentNavItem.isDisabled = false
    currentNavItem.el.classList.remove('is-invalid', 'is-valid')

    this.disableButtons()
  }

  private disableNavItemActions(item: IStepperItem) {
    item.isDisabled = true
    item.el.classList.add('disabled')
  }

  private enableNavItemActions(item: IStepperItem) {
    item.isDisabled = false
    item.el.classList.remove('disabled')
  }

  // Buttons
  private buildButtons() {
    this.backBtn = this.el.querySelector('[data-stepper-back-btn]')
    this.nextBtn = this.el.querySelector('[data-stepper-next-btn]')
    this.skipBtn = this.el.querySelector('[data-stepper-skip-btn]')
    this.completeStepBtn = this.el.querySelector('[data-stepper-complete-step-btn]')
    this.finishBtn = this.el.querySelector('[data-stepper-finish-btn]')
    this.resetBtn = this.el.querySelector('[data-stepper-reset-btn]')

    this.buildBackButton()
    this.buildNextButton()
    this.buildSkipButton()
    this.buildCompleteStepButton()
    this.buildFinishButton()
    this.buildResetButton()
  }

  // back
  private buildBackButton() {
    if (!this.backBtn) return

    this.checkForTheFirstStep()

    this.onBackClickListener = () => this.backClick()

    this.backBtn.addEventListener('click', this.onBackClickListener)
  }

  private handleBackButtonClick() {
    if (this.currentIndex === 1) return

    if (this.mode === 'linear') {
      this.removeOptionalClasses()
    }

    this.currentIndex--

    if (this.mode === 'linear') {
      this.removeOptionalClasses()
    }

    this.setCurrentNavItem()
    this.setCurrentContentItem()

    this.checkForTheFirstStep()
    if (this.completeStepBtn) {
      this.changeTextAndDisableCompleteButtonIfStepCompleted()
    }

    this.fireEvent('back', this.currentIndex)
    dispatch('back.stepper', this.el, this.currentIndex)
  }

  private checkForTheFirstStep() {
    if (this.currentIndex === 1) {
      this.setToDisabled(this.backBtn)
    } else {
      this.setToNonDisabled(this.backBtn)
    }
  }

  private setToDisabled(el: HTMLElement) {
    if (el.tagName === 'BUTTON' || el.tagName === 'INPUT') {
      el.setAttribute('disabled', 'disabled')
    }

    el.classList.add('disabled')
  }

  private setToNonDisabled(el: HTMLElement) {
    if (el.tagName === 'BUTTON' || el.tagName === 'INPUT') {
      el.removeAttribute('disabled')
    }

    el.classList.remove('disabled')
  }

  // next
  private buildNextButton() {
    if (!this.nextBtn) return

    this.onNextClickListener = () => this.nextClick()

    this.nextBtn.addEventListener('click', this.onNextClickListener)
  }

  private unsetProcessedNavItemActions(item: IStepperItem) {
    item.isProcessed = false

    item.el.classList.remove('processed')
  }

  private handleNextButtonClick(infinite = true) {
    if (infinite) {
      if (this.currentIndex === this.totalSteps) this.currentIndex = 1
      else this.currentIndex++
    } else {
      const nonCompletedSteps = this.getUncompletedSteps()

      if (nonCompletedSteps.length === 1) {
        const { index } = nonCompletedSteps[0]

        this.currentIndex = index
      } else {
        if (this.currentIndex === this.totalSteps) return

        this.currentIndex++
      }
    }

    if (this.mode === 'linear') {
      this.removeOptionalClasses()
    }

    this.setCurrentNavItem()
    this.setCurrentContentItem()

    this.checkForTheFirstStep()
    if (this.completeStepBtn) {
      this.changeTextAndDisableCompleteButtonIfStepCompleted()
    }

    this.showSkipButton()
    this.showFinishButton()
    this.showCompleteStepButton()

    this.fireEvent('next', this.currentIndex)
    dispatch('next.stepper', this.el, this.currentIndex)
  }

  private removeOptionalClasses() {
    const currentNavItem = this.navItems.find(({ index }) => index === this.currentIndex)
    const currentContentItem = this.contentItems.find(({ index }) => index === this.currentIndex)

    currentNavItem.isSkip = false
    currentNavItem.isInvalid = false
    currentNavItem.isDisabled = false
    currentContentItem.isSkip = false

    currentNavItem.el.classList.remove('skipped', 'is-valid', 'is-invalid')
    currentContentItem.el.classList.remove('skipped', 'is-valid', 'is-invalid')
  }

  // skip
  private buildSkipButton() {
    if (!this.skipBtn) return

    this.showSkipButton()

    this.onSkipClickListener = () => this.skipClick()

    this.skipBtn.addEventListener('click', this.onSkipClickListener)
  }

  private setSkipItem(n?: number) {
    const targetNavItem = this.navItems.find(({ index }) => index === (n || this.currentIndex))
    const targetContentItem = this.contentItems.find(({ index }) => index === (n || this.currentIndex))

    if (!targetNavItem || !targetContentItem) return

    this.setSkipItemActions(targetNavItem)
    this.setSkipItemActions(targetContentItem)
  }

  private setSkipItemActions(item: IStepperItem) {
    item.isSkip = true

    item.el.classList.add('skipped')
  }

  private showSkipButton() {
    if (!this.skipBtn) return

    const { isOptional } = this.navItems.find(({ index }) => index === this.currentIndex)

    if (isOptional) this.skipBtn.style.display = ''
    else this.skipBtn.style.display = 'none'
  }

  private handleSkipButtonClick() {
    this.setSkipItem()
    this.handleNextButtonClick()

    this.fireEvent('skip', this.currentIndex)
    dispatch('skip.stepper', this.el, this.currentIndex)
  }

  // complete
  private buildCompleteStepButton() {
    if (!this.completeStepBtn) return

    this.completeStepBtnDefaultText = this.completeStepBtn.innerText

    this.onCompleteStepBtnClickListener = () => this.completeStepBtnClick()

    this.completeStepBtn.addEventListener('click', this.onCompleteStepBtnClickListener)
  }

  private changeTextAndDisableCompleteButtonIfStepCompleted() {
    const currentNavItem = this.navItems.find(({ index }) => index === this.currentIndex)
    const { completedText } = JSON.parse(this.completeStepBtn.getAttribute('data-stepper-complete-step-btn'))

    if (!currentNavItem) return

    if (currentNavItem.isCompleted) {
      this.completeStepBtn.innerText = completedText || this.completeStepBtnDefaultText
      this.completeStepBtn.setAttribute('disabled', 'disabled')
      this.completeStepBtn.classList.add('disabled')
    } else {
      this.completeStepBtn.innerText = this.completeStepBtnDefaultText
      this.completeStepBtn.removeAttribute('disabled')
      this.completeStepBtn.classList.remove('disabled')
    }
  }

  private setCompleteItem(n?: number) {
    const targetNavItem = this.navItems.find(({ index }) => index === (n || this.currentIndex))
    const targetContentItem = this.contentItems.find(({ index }) => index === (n || this.currentIndex))

    if (!targetNavItem || !targetContentItem) return

    this.setCompleteItemActions(targetNavItem)
    this.setCompleteItemActions(targetContentItem)
  }

  private setCompleteItemActions(item: IStepperItem) {
    item.isCompleted = true

    item.el.classList.add('is-valid')
  }

  private showCompleteStepButton() {
    if (!this.completeStepBtn) return

    const nonCompletedSteps = this.getUncompletedSteps()

    if (nonCompletedSteps.length === 1) {
      this.completeStepBtn.style.display = 'none'
    } else this.completeStepBtn.style.display = ''
  }

  private handleCompleteStepButtonClick() {
    this.setCompleteItem()

    this.fireEvent('complete', this.currentIndex)
    dispatch('complete.stepper', this.el, this.currentIndex)

    this.handleNextButtonClick(false)
    this.showFinishButton()
    this.showCompleteStepButton()
    this.checkForTheFirstStep()
    if (this.completeStepBtn) {
      this.changeTextAndDisableCompleteButtonIfStepCompleted()
    }
    this.showSkipButton()
  }

  // finish
  private buildFinishButton() {
    if (!this.finishBtn) return

    if (this.isCompleted) {
      this.setCompleted()
    }

    this.onFinishBtnClickListener = () => this.finishBtnClick()

    this.finishBtn.addEventListener('click', this.onFinishBtnClickListener)
  }

  private setCompleted() {
    this.el.classList.add('completed')
  }

  private unsetCompleted() {
    this.el.classList.remove('completed')
  }

  private showFinishButton() {
    if (!this.finishBtn) return

    const nonCompletedSteps = this.getUncompletedSteps()

    if (nonCompletedSteps.length === 1) this.finishBtn.style.display = ''
    else this.finishBtn.style.display = 'none'
  }

  private handleFinishButtonClick() {
    const uncompletedSteps = this.getUncompletedSteps()
    const uncompletedOrSkipSteps = this.getUncompletedSteps(true)
    const { el } = this.contentItems.find(({ isFinal }) => isFinal)

    if (uncompletedSteps.length) {
      uncompletedSteps.forEach(({ index }) => this.setCompleteItem(index))
    }

    this.currentIndex = this.totalSteps

    this.setCurrentNavItem()
    this.hideAllContentItems()

    const currentNavItem = this.navItems.find(({ index }) => index === this.currentIndex)
    const currentNavItemEl = currentNavItem ? currentNavItem.el : null

    currentNavItemEl.classList.remove('active')

    el.style.display = 'block'
    if (this.backBtn) this.backBtn.style.display = 'none'
    if (this.nextBtn) this.nextBtn.style.display = 'none'
    if (this.skipBtn) this.skipBtn.style.display = 'none'
    if (this.completeStepBtn) this.completeStepBtn.style.display = 'none'
    if (this.finishBtn) this.finishBtn.style.display = 'none'
    if (this.resetBtn) this.resetBtn.style.display = ''

    if (uncompletedOrSkipSteps.length <= 1) {
      this.isCompleted = true
      this.setCompleted()
    }

    this.fireEvent('finish', this.currentIndex)
    dispatch('finish.stepper', this.el, this.currentIndex)
  }

  // reset
  private buildResetButton() {
    if (!this.resetBtn) return

    this.onResetBtnClickListener = () => this.resetBtnClick()

    this.resetBtn.addEventListener('click', this.onResetBtnClickListener)
  }

  private handleResetButtonClick() {
    if (this.backBtn) this.backBtn.style.display = ''
    if (this.nextBtn) this.nextBtn.style.display = ''
    if (this.completeStepBtn) {
      this.completeStepBtn.style.display = ''
      this.completeStepBtn.innerText = this.completeStepBtnDefaultText
      this.completeStepBtn.removeAttribute('disabled')
      this.completeStepBtn.classList.remove('disabled')
    }
    if (this.resetBtn) this.resetBtn.style.display = 'none'

    this.navItems.forEach(item => {
      const { el } = item
      item.isSkip = false
      item.isCompleted = false

      this.unsetCurrentNavItemActions(el)
      el.classList.remove('is-valid', 'skipped')
    })

    this.contentItems.forEach(item => {
      const { el } = item
      item.isSkip = false
      item.isCompleted = false

      this.unsetCurrentContentItemActions(el)
      el.classList.remove('is-valid', 'skipped')
    })

    this.currentIndex = 1

    this.unsetCompleted()
    this.isCompleted = false

    this.showSkipButton()
    this.setCurrentNavItem()
    this.setCurrentContentItem()
    this.showFinishButton()
    this.showCompleteStepButton()
    this.checkForTheFirstStep()

    this.fireEvent('reset', this.currentIndex)
    dispatch('reset.stepper', this.el, this.currentIndex)
  }

  // Public methods
  public setProcessedNavItem(n?: number) {
    const targetNavItem = this.getNavItem(n)

    if (!targetNavItem) return

    this.setProcessedNavItemActions(targetNavItem)
  }

  public unsetProcessedNavItem(n?: number) {
    const targetNavItem = this.getNavItem(n)

    if (!targetNavItem) return

    this.unsetProcessedNavItemActions(targetNavItem)
  }

  public goToNext() {
    if (this.mode === 'linear') this.setCompleteItem()

    this.handleNextButtonClick(this.mode !== 'linear')

    if (this.mode === 'linear' && this.currentIndex === this.totalSteps) {
      if (this.nextBtn) this.nextBtn.style.display = 'none'
      if (this.completeStepBtn) this.completeStepBtn.style.display = 'none'
    }
  }

  public goToFinish() {
    this.handleFinishButtonClick()
  }

  public disableButtons() {
    if (this.backBtn) this.setToDisabled(this.backBtn)
    if (this.nextBtn) this.setToDisabled(this.nextBtn)
  }

  public enableButtons() {
    if (this.backBtn) this.setToNonDisabled(this.backBtn)
    if (this.nextBtn) this.setToNonDisabled(this.nextBtn)
  }

  public setErrorNavItem(n?: number) {
    const targetNavItem = this.getNavItem(n)

    if (!targetNavItem) return

    this.setErrorNavItemActions(targetNavItem)
  }

  public destroy() {
    // Remove classes
    this.el.classList.remove('completed')
    this.el.querySelectorAll('[data-stepper-nav-item]').forEach(el => {
      el.classList.remove('active', 'is-valid', 'skipped', 'disabled', 'is-invalid')

      if (el.tagName === 'BUTTON' || el.tagName === 'INPUT') {
        el.removeAttribute('disabled')
      }
    })
    this.el.querySelectorAll('[data-stepper-content-item]').forEach(el => {
      el.classList.remove('is-valid', 'skipped')
    })
    if (this.backBtn) this.backBtn.classList.remove('disabled')
    if (this.nextBtn) this.nextBtn.classList.remove('disabled')
    if (this.completeStepBtn) this.completeStepBtn.classList.remove('disabled')

    // Remove attributes
    if (this.backBtn) this.backBtn.style.display = ''
    if (this.nextBtn) this.nextBtn.style.display = ''
    if (this.skipBtn) this.skipBtn.style.display = ''
    if (this.finishBtn) this.finishBtn.style.display = 'none'
    if (this.resetBtn) this.resetBtn.style.display = 'none'

    // Remove listeners
    if (this.onNavItemClickListener.length) {
      this.onNavItemClickListener.forEach(({ el, fn }) => {
        el.removeEventListener('click', fn)
      })
    }
    if (this.backBtn) {
      this.backBtn.removeEventListener('click', this.onBackClickListener)
    }
    if (this.nextBtn) {
      this.nextBtn.removeEventListener('click', this.onNextClickListener)
    }
    if (this.skipBtn) {
      this.skipBtn.removeEventListener('click', this.onSkipClickListener)
    }
    if (this.completeStepBtn) {
      this.completeStepBtn.removeEventListener('click', this.onCompleteStepBtnClickListener)
    }
    if (this.finishBtn) {
      this.finishBtn.removeEventListener('click', this.onFinishBtnClickListener)
    }
    if (this.resetBtn) {
      this.resetBtn.removeEventListener('click', this.onResetBtnClickListener)
    }

    window.$hsStepperCollection = window.$hsStepperCollection.filter(({ element }) => element.el !== this.el)
  }

  // Static methods
  static getInstance(target: HTMLElement | string, isInstance?: boolean) {
    const elInCollection = window.$hsStepperCollection.find(
      el => el.element.el === (typeof target === 'string' ? document.querySelector(target) : target)
    )

    return elInCollection ? (isInstance ? elInCollection : elInCollection.element) : null
  }

  static autoInit() {
    if (!window.$hsStepperCollection) window.$hsStepperCollection = []

    if (window.$hsStepperCollection) {
      window.$hsStepperCollection = window.$hsStepperCollection.filter(({ element }) => document.contains(element.el))
    }

    document.querySelectorAll('[data-stepper]:not(.--prevent-on-load-init)').forEach((el: HTMLElement) => {
      if (!window.$hsStepperCollection.find(elC => (elC?.element?.el as HTMLElement) === el)) {
        new HSStepper(el)
      }
    })
  }
}

declare global {
  interface Window {
    HSStepper: Function
    $hsStepperCollection: ICollectionItem<HSStepper>[]
  }
}

window.addEventListener('load', () => {
  HSStepper.autoInit()

  // Uncomment for debug
  // console.log('Stepper collection:', window.$hsStepperCollection);
})

if (typeof window !== 'undefined') {
  window.HSStepper = HSStepper
}

export default HSStepper
